package com.tbit.uqbike.webmanager.controller;

import com.huifu.adapay.core.AdapayCore;
import com.huifu.adapay.core.util.AdapaySign;
import com.huifu.adapay.model.CorpMember;
import com.huifu.adapay.model.Member;
import com.huifu.adapay.model.SettleAccount;
import com.tbit.common.utils.TraceUtil;
import com.tbit.uqbike.constant.OperaPswConstant;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.uqbike.service.business.AdaPayConfigService;
import com.tbit.uqbike.service.business.AdaPayService;
import com.tbit.uqbike.service.business.OperaPswService;
import com.tbit.uqbike.service.business.UserAdapayLogService;
import com.tbit.uqbike.webmanager.util.adaPay.AdaPayUtil;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.utils.Assert;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @ClassName adaPayController
 * @Description 分账业务层
 * @date 2021/10/21 10:14
 * @Version 1.0
 */

@RestController
@RequestMapping("/adaPay")
@Slf4j
public class AdaPayController extends BaseController {
    @Autowired
    private AdaPayService adaPayService;
    @Autowired
    private AdaPayConfigService adaPayConfigService;
    @Autowired
    private UserAdapayLogService userAdapayLogService;
    @Autowired
    private OperaPswService operaPswService;

    /**
     * 解析传过来的KV值
     */
    public static Map<String, Object> initKV(String paramKV) {
        /**处理传过来的Key-Value类型的值*/
        Map<String, Object> map = new HashMap<>();
        if (null != paramKV) {
            List<String> TimeLists = Stream.of(paramKV.split(";")).collect(Collectors.toList());
            for (String timeList : TimeLists) {
                List<String> list = Stream.of(timeList.split(":")).collect(Collectors.toList());
                if (list.size() >= 2) {
                    for (int i = 0; i < 1; i++) {
                        map.put(list.get(0), list.get(1));
                    }
                }
            }
        }
        return map;
    }

    /**
     * MultipartFile转换为File文件
     */
    public static File MultipartFileToFile(MultipartFile multiFile) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        // 若须要防止生成的临时文件重复,能够在文件名后添加随机码

        try {
            File file = File.createTempFile(fileName, prefix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * @描述 增加分账用户
     * @参数
     * @返回值
     * @创建人 hzw
     * @创建时间 2021/10/21
     * @修改人和其它信息
     */
    //@Transactional
    @PostMapping("/addAccount")
    public JsonResult AddAccount(SeparateAccount separateAccount, HttpServletRequest request) throws Exception {

        Map<String, Object> map = initKV(separateAccount.getParamKV());
        AdaPayConfig adaPayConfig = new AdaPayConfig();
//        /**当传过来的是区域id*/
//        if (null == separateAccount.getAccountId()) {
//            /**根据区域id找到相对应的品牌id*/
//            Account account = accountService.getAgentId(separateAccount.getSeparateAccountId());
//            adaPayConfig = adaPayConfigService.getInfoByAccountId(account.getAccountId());
//            separateAccount.setAccountId(account.getAccountId());
//        } else {
//            adaPayConfig = adaPayConfigService.getInfoByAccountId(separateAccount.getAccountId());
//        }
        adaPayConfig = adaPayConfigService.getInfoByAccountId(separateAccount.getAccountId());
        AdaPayUtil.initConfig(adaPayConfig);

        Assert.notNull(map.get("mainUser"), "未选择是否为主账号");
        Assert.notNull(map.get("userName"), "请输入昵称");

        /**判断是否已经存在主账号了*/
        if (Integer.parseInt(map.get("mainUser").toString()) == 1) {
            List<SeparateAccount> accountList = adaPayService.getAccountByIdNo(separateAccount);
            for (SeparateAccount account : accountList) {
                if ("1".equals(initKV(account.getParamKV()).get("mainUser").toString())) {
                    throw new BaseException(SystemCodeEnum.PRINCIPAL_ACCOUNT_HAVE_EXIST);
                }
            }
        }
        /**判断是否已经存在昵称*/
        if (null != map.get("userName")) {
            List<SeparateAccount> accountList = adaPayService.getInfoByAccountId(separateAccount.getAccountId());
            for (SeparateAccount account : accountList) {
                if (initKV(account.getParamKV()).get("userName").equals(map.get("userName"))) {
                    throw new BaseException(SystemCodeEnum.DUPKLICATE_NAME);
                }
            }
        }

        /**创建用户或者企业的参数*/
        Map<String, Object> memberParams = new HashMap(2);
        /**创建结算账户的参数*/
        Map<String, Object> settleCountParams = new HashMap(2);
        Map<String, Object> accountInfo = new HashMap(2);
        Map<String, Object> member = new HashMap<>();
        memberParams.put("member_id", "uqbike_member_" + System.currentTimeMillis());
        memberParams.put("app_id", adaPayConfig.getAppId());

        /**创建个人账户*/
        if (separateAccount.getAccountType() == 0) {
            accountInfo.put("bank_acct_type", 2);
            accountInfo.put("cert_id", separateAccount.getIdNo());
            accountInfo.put("cert_type", "00");
            /**创建分账账户*/
            member = Member.create(memberParams);
            if (member.get("error_msg") != null) {
                return JsonResult.fail(member.get("error_msg").toString(), TraceUtil.getTraceIdByLocal());
            }
            accountInfo.put("card_id", separateAccount.getBankCard());
            accountInfo.put("card_name", separateAccount.getAccountName());
            accountInfo.put("tel_no", separateAccount.getPhone());
            settleCountParams.put("member_id", member.get("member_id"));
            settleCountParams.put("app_id", member.get("app_id"));
            settleCountParams.put("channel", "bank_account");
            settleCountParams.put("account_info", accountInfo);
            /**创建个人结算账户，绑卡*/
            Map<String, Object> settleCount = SettleAccount.create(settleCountParams);
            /**创建结算账户失败*/
            if (settleCount.get("error_msg") != null) {
                separateAccount.setAppId(member.get("app_id").toString());
                separateAccount.setMemberId(member.get("member_id").toString());
                separateAccount.setSeparateAccountId(separateAccount.getAccountId());
                adaPayService.addAccount(separateAccount);
                return JsonResult.fail("创建结算账户失败,请重新创建结算账户",TraceUtil.getTraceIdByLocal());
            }
            separateAccount.setSettleNo(settleCount.get("id").toString());
            /**创建企业账户*/
        } else {
            memberParams.put("name", map.get("name"));
            memberParams.put("prov_code", map.get("prov_code"));
            memberParams.put("area_code", map.get("area_code"));
            memberParams.put("social_credit_code", map.get("social_credit_code"));
            memberParams.put("social_credit_code_expires", map.get("social_credit_code_expires"));
            memberParams.put("business_scope", map.get("business_scope"));
            memberParams.put("legal_person", separateAccount.getAccountName());
            memberParams.put("legal_cert_id", separateAccount.getIdNo());
            memberParams.put("legal_cert_id_expires", map.get("legal_cert_id_expires"));
            memberParams.put("legal_mp", separateAccount.getPhone());
            memberParams.put("address", map.get("address"));
            memberParams.put("bank_code", map.get("bank_code"));
            memberParams.put("bank_acct_type", "1");
            memberParams.put("card_no", separateAccount.getBankCard());
            memberParams.put("card_name", map.get("name1"));
            memberParams.put("notify_url", OperaPswConstant.NOTIFY_URL);
            memberParams.put("order_no", "uqbike_QiYe" + System.currentTimeMillis());
            File file = MultipartFileToFile(separateAccount.getAttach_file());
            member = CorpMember.create(memberParams, file);
            if (member.get("error_msg") != null) {
                return JsonResult.fail(member.get("error_msg").toString(),TraceUtil.getTraceIdByLocal());
            }
        }
        separateAccount.setAppId(member.get("app_id").toString());
        separateAccount.setMemberId(member.get("member_id").toString());
        separateAccount.setSeparateAccountId(separateAccount.getAccountId());
        adaPayService.addAccount(separateAccount);
        return JsonResult.ok();
    }

    /**
     * 分账账户更新
     */
    @RequestMapping(value = "/updateAccount")
    public JsonResult UpdateAccount(SeparateAccount separateAccount) throws Exception {
        AdaPayConfig adaPayConfig = adaPayConfigService.getInfoByAccountId(separateAccount.getAccountId());
        AdaPayUtil.initConfig(adaPayConfig);
        Map<String, Object> map = initKV(separateAccount.getParamKV());

        adaPayService.updateAccount(separateAccount);

        Map<String, Object> memberParams = new HashMap<String, Object>(2);
        memberParams.put("accountId", separateAccount.getAccountId());
        memberParams.put("member_id", separateAccount.getMemberId());
        memberParams.put("app_id", adaPayConfig.getAppId());
        memberParams.put("tel_no", separateAccount.getPhone());
        memberParams.put("nickname", separateAccount.getAccountName());

        Map<String, Object> member = Member.update(memberParams);

        return JsonResult.ok(member);
    }

    /**
     * 禁用、启用、删除账户
     */
    @RequestMapping("/disableAccount")
    public JsonResult disableAccount(SeparateAccount separateAccount) {
        /**操作密码校验*/
        if (!OperaPswConstant.ADMIN_OPERA_PSW.equals(separateAccount.getOperaPsw())) {
            throw new BaseException(SystemCodeEnum.OPERA_PAW_ERROR);
        }

        Assert.notNull(separateAccount.getAccountId(), "ver.accountId.notNull");
        Assert.notNull(separateAccount.getMemberId(), "memberId不能为空");
        /**禁用分账账户*/
        adaPayService.disableAccount(separateAccount);
        /**禁用结算账户*/
        UserDivide userDivide = new UserDivide();
        userDivide.setUserNO(separateAccount.getMemberId());
        userDivide.setState(separateAccount.getState());
        adaPayConfigService.upRatioState(userDivide);
        return JsonResult.ok();
    }

    /**
     * 查看单个分账账户
     */
    @RequestMapping("/queryMember")
    public JsonResult QueryMember(SeparateAccount separateAccount) {
        Assert.notNull(separateAccount.getAccountId(), "ver.accountId.notNull");
        Assert.notNull(separateAccount.getMemberId(), "memberId不能为空");
        AdaPayConfig adaPayConfig = adaPayConfigService.getInfoByAccountId(separateAccount.getAccountId());
        if (null != adaPayConfig) {
            separateAccount.setAppId(adaPayConfig.getAppId());
        }
        SeparateAccount account = adaPayService.getAccount(separateAccount);
        if (account != null) {
            return JsonResult.ok(account);
        } else {
            return JsonResult.ok();
        }
    }

    /**
     * 查看分账账户列表
     */
    @RequestMapping("/queryPage")
    public JsonResult QueryPage(Integer accountId, Integer pageNO, Integer rowCount) throws Exception {
        AdaPayConfig adaPayConfig = adaPayConfigService.getInfoByAccountId(accountId);
        AdaPayUtil.initConfig(adaPayConfig);
        Map<String, Object> memberParams = new HashMap<String, Object>(2);
        List<SeparateAccount> list = adaPayService.getAccountList(accountId, pageNO, rowCount);
        Integer count = adaPayService.getAccountCount(accountId);
        if (list.size() > 0) {
            return JsonResult.ok(list, count);
        }
        memberParams.put("page_index", pageNO);
        memberParams.put("app_id", adaPayConfig.getAppId());
        memberParams.put("page_size", rowCount);
        memberParams.put("created_gte", "16353130000");
        memberParams.put("created_lte", System.currentTimeMillis());
        Map<String, Object> member = Member.queryList(memberParams);

        return JsonResult.ok(member);

    }

    /**
     * @描述 分账比例设置
     * @参数
     * @返回值
     * @创建人 hzw
     * @创建时间 2021/10/27
     * @修改人和其它信息
     */
    @RequestMapping("/editRatio")
    //@Transactional
    public JsonResult addRatio(SeparateAccount separateAccount) {
        /**获取分账比例*/
        Map<String, Object> memberParams = initKV(separateAccount.getSeparateRatio());
        List<MapKV> mapKVList = new ArrayList<>();
        memberParams.forEach((key, value) -> {
            MapKV mapKV = new MapKV();
            mapKV.setKey(key);
            mapKV.setValue(value);
            mapKVList.add(mapKV);
        });
        /**获取总共分账比例之和*/
        int total = mapKVList.stream().mapToInt(Employee -> Integer.parseInt(Employee.getValue().toString())).sum();
        /**分账比例之和必须为100*/
        if (total != 100) {
            throw new BaseException(SystemCodeEnum.SUM_NOT_HUNDRED);
        }
        /**删除区域下所有的账户信息*/
        adaPayConfigService.delRatioInfo(separateAccount.getAccountId());

        for (MapKV mapKV : mapKVList) {
            SeparateAccount SepAccount = adaPayService.getAccount(new SeparateAccount(mapKV.getKey()));
            /**处理传过来的Key-Value类型的值*/
            Map<String, Object> map = initKV(SepAccount.getParamKV());
            UserDivide userDivide = new UserDivide();
            userDivide.setAccountId(separateAccount.getAccountId());
            userDivide.setAddTime(new Date());
            userDivide.setSettleNO(SepAccount.getSettleNo());
            userDivide.setName(SepAccount.getAccountName());
            userDivide.setProportion(Double.parseDouble(mapKV.getValue().toString()));
            userDivide.setPhone(SepAccount.getPhone());
            userDivide.setUserNO(SepAccount.getMemberId());
            userDivide.setMainUser(Integer.parseInt(map.get("mainUser").toString()));
            userDivide.setState(SepAccount.getState());
            adaPayConfigService.addRatio(userDivide);
        }
        return JsonResult.ok();
    }

    /**
     * @描述 分账比例设置
     * @参数
     * @返回值
     * @创建人 hzw
     * @创建时间 2021/10/27
     * @修改人和其它信息
     */
    @RequestMapping("/getRatio")
    public JsonResult getRatio(Integer accountId, @RequestParam(defaultValue = "10") Integer rowCount,
                               @RequestParam(defaultValue = "1") Integer pageNO) {
        Assert.notNull(accountId, "ver.accountId.notNull");
        List<UserDivide> userDivideList = adaPayConfigService.getByAccountId(accountId, rowCount, pageNO);
        for (UserDivide userDivide : userDivideList) {
            userDivide.setUserName(initKV(userDivide.getParamKV()).get("userName").toString());
        }
        return JsonResult.ok(userDivideList, userDivideList.size());
    }

    /**
     * @描述 查看分账详情
     * @参数
     * @返回值
     * @创建人 hzw
     * @创建时间 2021/11/6
     * @修改人和其它信息
     */
    @GetMapping("/RatioPage")
    public JsonResult RatioPage(UserAdapayLog userAdapayLog) {
        List<UserAdapayLog> list = userAdapayLogService.getInfoByMemberId(userAdapayLog);
        return JsonResult.ok(startPage(list), list.size());
    }

    /**
     * 导出分账详情
     */
    @RequestMapping("/export")
    public JsonResult export(@RequestBody UserAdapayLog userAdapayLog) {
        List<UserAdapayLog> list = userAdapayLogService.getInfoByMemberId(userAdapayLog);
        ExcelUtil<UserAdapayLog> util = new ExcelUtil<UserAdapayLog>(UserAdapayLog.class);
        return util.exportExcel(list, "分账详情数据");
    }

    /**
     * 创建企业账户审核的回调函数
     */
    @PostMapping("/callback")
    public void callback(HttpServletRequest request) {
        try {
            //验签请参data
            String data = request.getParameter("data");
            //验签请参sign
            String sign = request.getParameter("sign");
            //验签标记
            boolean checkSign;
            //验签请参publicKey
            String publicKey = AdapayCore.PUBLIC_KEY;
            log.info("验签请参：data={}sign={}");
            //验签
            checkSign = AdapaySign.verifySign(data, sign, publicKey);
            if (checkSign) {
                System.out.println("成功返回数据data:" + data);
                /**验签成功逻辑*/
                JSONObject jsonObj = new JSONObject(data);
                JSONObject jsonObject = new JSONObject(jsonObj.get("data"));
                /**获取企业账户审核通过后的结算账户id*/
                String settleAccountId = jsonObject.getString("settle_account_id");
                String memberId = jsonObj.getString("member_id");
                SeparateAccount separateAccount = new SeparateAccount();
                separateAccount.setMemberId(memberId);
                separateAccount.setSettleNo(settleAccountId);
                adaPayService.updateAccount(separateAccount);
            } else {
                /**验签失败逻辑*/
                JSONObject jsonObj = new JSONObject(data);
                JSONObject jsonObject = new JSONObject(jsonObj.get("data"));
                /**企业账户审核失败返回的提示*/
                String AuditDesc = jsonObject.getString("audit_desc");
                throw new BaseException(AuditDesc);
            }
        } catch (Exception e) {
            log.info("异步回调开始，参数，request={}");
        }
    }


}
